有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java 8流/收集器按地图分组

我有两张地图

  1. scoreMap<String,Float>以组名作为键及其 分数作为价值
  2. ^有阈值的{} 作为关键,相关评论作为价值
  3. 我得想出个办法 Map<String,List<String>>来自此。把它读成Map<comment,List of groups its applicable to>Map<group, comment>也可以

逻辑就是从scoresMap中获取score,并将其与threshold映射中的threshold进行比较。根据它落在哪里(即高于高位、介于高位和中档之间或低于中档),从^{中选择相关的注释

可能是这样的:

BiFunction<Map<String,Float>, Map<Float,String>, Map<String,String>> or
BiFunction<Map<String,Float>, Map<Float,String>, Map<String,List<String>>>

我还没有弄明白如何使用检查3个条件的Predicate来执行groupingBy,所以对于没有其他样本Stream代码表示歉意!非流代码如下所示(不使用映射):

if(orgScorePct >= HI_THRESHOLD) 
    return "ORG_HI_SCORE_COMMENT";
if(orgScorePct < HI_THRESHOLD && orgScorePct > MED_THRESHOLD) 
    return "ORG_MED_SCORE_COMMENT";
return "ORG_LOW_SCORE_COMMENT";

共 (2) 个答案

  1. # 1 楼答案

    首先,使用TreeMap作为阈值要容易得多:因为它是键上的一个排序映射,为给定值确定正确的阈值注释只需获取该值的^{}。天花板入口对应于在给定入口下方有一把钥匙的入口。类似地,有^{}来检索在给定项之后有一个键的项

    考虑到这一点,我们可以有以下(样本数据):

    Map<String,Float> scoreMap = new HashMap<>();
    TreeMap<Float,String> thresholdMap = new TreeMap<>();
    
    scoreMap.put("name1", 1.0f);
    scoreMap.put("name2", 2.0f);
    scoreMap.put("name3", 3.0f);
    scoreMap.put("name4", 5.0f);
    
    thresholdMap.put(0.5f, "comment0");
    thresholdMap.put(1.5f, "comment1");
    thresholdMap.put(4.5f, "comment2");
    
    Map<String,List<String>> result =
        scoreMap.entrySet()
                .stream()
                .collect(Collectors.groupingBy(
                    e -> thresholdMap.floorEntry(e.getValue()).getValue(),
                    Collectors.mapping(Map.Entry::getKey, Collectors.toList())
                ));
    

    这导致了{comment2=[name4], comment1=[name3, name2], comment0=[name1]},这是正确的:"comment2"的阈值为4.5,只有"name4"的得分大于该值;{}的阈值为1.5,{}和{}的得分都在1.5到4.5之间,以此类推

    如果没有楼层入口,请小心:可能是分数没有相应的阈值;例如,在上面的数据中,分数为0会导致问题。要处理这种情况,需要检查floorEntry是否返回null,并通过返回默认值来相应地处理它

  2. # 2 楼答案

        List<BeanClass> list1 = new ArrayList<BeanClass>();
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        list1.add(new BeanClass(123,abc,99.0,formatter.parse("2018-02-01")));
        list1.add(new BeanClass(456,xyz,99.0,formatter.parse("2014-01-01")));
        list1.add(new BeanClass(789,pqr,95.0,formatter.parse("2014-01-01")));
        list1.add(new BeanClass(1011,def,99.0,formatter.parse("2014-01-01")));
        Map<Object, Optional<Double>> byDate = list1.stream()
       .collect(Collectors.groupingBy(p -> formatter.format(p.getCurrentDate()),
        Collectors.mapping(BeanClass::getAmount, Collectors.maxBy(Double::compare))));